/*
 * Copyright 2012-2021 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.boot;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Indexed;

/**
 * 表示该类提供 Spring Boot 应用的
 * {@link Configuration @Configuration}。可以作为 Spring 标准 {@code @Configuration} 注解的替代，
 * 以便配置可以被自动发现（例如在测试中）。
 * <p>
 * 应用中应且只能包含 <em>一个</em> {@code @SpringBootConfiguration}，
 * 大多数惯用的 Spring Boot 应用会从 {@code @SpringBootApplication} 继承它。
 *
 * @author Phillip Webb
 * @author Andy Wilkinson
 * @since 1.4.0
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
@Indexed
public @interface SpringBootConfiguration {

	/**
	 * 指定是否应对 {@link Bean @Bean} 方法进行代理，以强制执行 bean 生命周期行为，
	 * 例如即使在用户代码中直接调用 {@code @Bean} 方法时也返回共享的单例 bean 实例。
	 * 此功能需要方法拦截，通过运行时生成的 CGLIB 子类实现，
	 * 但这带来一些限制，比如配置类及其方法不能声明为 {@code final}。
	 * <p>
	 * 默认值为 {@code true}，允许配置类内部的“bean 之间引用”以及外部调用该配置的
	 * {@code @Bean} 方法（例如来自另一个配置类）。
	 * 如果不需要此功能（因为该配置类中的每个 {@code @Bean} 方法都是自包含的，
	 * 并且设计为容器使用的普通工厂方法），可以将此标志设置为 {@code false}，
	 * 以避免 CGLIB 子类处理。
	 * <p>
	 * 关闭 bean 方法拦截后，会像在非 {@code @Configuration} 类上声明一样，
	 * 单独处理 {@code @Bean} 方法，也称为“@Bean 精简模式”（详见 {@link Bean @Bean 的 javadoc}）。
	 * 因此行为上等同于移除 {@code @Configuration} 立体类型。
	 * @return 是否代理 {@code @Bean} 方法
	 * @since 2.2
	 */
	@AliasFor(annotation = Configuration.class)
	boolean proxyBeanMethods() default true;

}
